//
//  CALayer+PopAnimation.m
//  XYZKitDemo
//
//  Created by 谢英泽 on 16/11/24.
//  Copyright © 2016年 谢英泽. All rights reserved.
//

#import "CALayer+PopAnimation.h"
#import <POP.h>

BOOL animatited;

NSString * const kLayerBackgroundColor        = @"backgroundColor";
NSString * const kLayerBounds                 = @"bounds";
NSString * const kLayerCornerRadius           = @"cornerRadius";
NSString * const kLayerBorderWidth            = @"borderWidth";
NSString * const kLayerBorderColor            = @"borderColor";
NSString * const kLayerOpacity                = @"opacity";
NSString * const kLayerPosition               = @"position";
NSString * const kLayerPositionX              = @"positionX";
NSString * const kLayerPositionY              = @"positionY";
NSString * const kLayerRotation               = @"rotation";
NSString * const kLayerRotationX              = @"rotationX";
NSString * const kLayerRotationY              = @"rotationY";
NSString * const kLayerScaleX                 = @"scaleX";
NSString * const kLayerScaleXY                = @"scaleXY";
NSString * const kLayerScaleY                 = @"scaleY";
NSString * const kLayerSize                   = @"size";
NSString * const kLayerSubscaleXY             = @"subscaleXY";
NSString * const kLayerSubtranslationX        = @"subtranslationX";
NSString * const kLayerSubtranslationXY       = @"subtranslationXY";
NSString * const kLayerSubtranslationY        = @"subtranslationY";
NSString * const kLayerSubtranslationZ        = @"subtranslationZ";
NSString * const kLayerTranslationX           = @"translationX";
NSString * const kLayerTranslationXY          = @"translationXY";
NSString * const kLayerTranslationY           = @"translationY";
NSString * const kLayerTranslationZ           = @"translationZ";
NSString * const kLayerZPosition              = @"zPosition";
NSString * const kLayerShadowColor            = @"shadowColor";
NSString * const kLayerShadowOffset           = @"shadowOffset";
NSString * const kLayerShadowOpacity          = @"shadowOpacity";
NSString * const kLayerShadowRadius           = @"shadowRadius";

@implementation CALayer (PopAnimation)

#pragma mark - Basic动画

- (void)layerBasicPopWithName:(NSString *)propertyNamed to:(id)toValue duration:(CGFloat)duration key:(NSString *)key complete:(kPopComplete)complete
{
    POPBasicAnimation *basicAnimation = [POPBasicAnimation animationWithPropertyNamed:propertyNamed];
    basicAnimation.toValue   = toValue;
    basicAnimation.duration = duration;
    basicAnimation.completionBlock = complete;
    [self pop_addAnimation:basicAnimation forKey:key];
}


- (void)layerBasicPopWithName:(NSString *)name from:(id)fromValue to:(id)toValue duration:(CGFloat)duration key:(NSString *)key complete:(kPopComplete)complete
{
    POPBasicAnimation *basicAnimation = [POPBasicAnimation animationWithPropertyNamed:name];
    basicAnimation.toValue   = toValue;
    basicAnimation.fromValue = fromValue;
    basicAnimation.duration = duration;
    basicAnimation.completionBlock = complete;
    [self pop_addAnimation:basicAnimation forKey:key];
}

#pragma mark - Spring动画

- (void)layerSpringPopWithName:(NSString *)propertyNamed to:(id)toValue bounce:(CGFloat)bounce speed:(CGFloat)speed key:(NSString *)key complete:(kPopComplete)complete
{
    POPSpringAnimation *springAnimation = [POPSpringAnimation animationWithPropertyNamed:propertyNamed];
    springAnimation.toValue    = toValue;
    springAnimation.springBounciness = bounce;
    springAnimation.springSpeed = speed;
    springAnimation.completionBlock = complete;
    [self pop_addAnimation:springAnimation forKey:key];
}

- (void)layerSpringPopWithName:(NSString *)propertyNamed to:(id)toValue bounce:(CGFloat)bounce speed:(CGFloat)speed key:(NSString *)key times:(id)times complete:(kPopComplete)complete
{
    POPSpringAnimation *springAnimation = [POPSpringAnimation animationWithPropertyNamed:propertyNamed];
    springAnimation.toValue    = toValue;
    springAnimation.springBounciness = bounce;
    springAnimation.springSpeed = speed;
    springAnimation.completionBlock = complete;
    if ([times intValue] == 0) {
        springAnimation.repeatCount = HUGE_VALF;
    }else{
        springAnimation.repeatCount = [times intValue];
    }
    [self pop_addAnimation:springAnimation forKey:key];
}

- (void)layerSpringPopWithName:(NSString *)propertyNamed from:(id)fromValue to:(id)toValue bounce:(CGFloat)bounce speed:(CGFloat)speed key:(NSString *)key complete:(kPopComplete)complete
{
    POPSpringAnimation *springAnimation = [POPSpringAnimation animationWithPropertyNamed:propertyNamed];
    springAnimation.fromValue  = fromValue;
    springAnimation.toValue    = toValue;
    springAnimation.springBounciness = bounce;
    springAnimation.springSpeed = speed;
    springAnimation.completionBlock = complete;
    [self pop_addAnimation:springAnimation forKey:key];
}

#pragma mark - Decay动画

- (void)layerDecayPopWithName:(NSString *)propertyNamed fromValue:(id)fromValue
{
    [self pop_removeAllAnimations];
    
    POPDecayAnimation *decayAnimation = [POPDecayAnimation animationWithPropertyNamed:propertyNamed];
    if (animatited) {
        decayAnimation.velocity = @(-60);
    }else{
        decayAnimation.velocity = @(60);
        decayAnimation.fromValue = fromValue;
    }
    animatited = !animatited;
    decayAnimation.completionBlock = ^(POPAnimation *anim, BOOL finished){
        if (finished) {
            [self layerDecayPopWithName:propertyNamed fromValue:fromValue];
        }
    };
    [self pop_addAnimation:decayAnimation forKey:nil];
}

#pragma mark - 移除动画

- (void)layerRemoveAllAnimations
{
    [self pop_removeAllAnimations];
}

#pragma mark - 震动动画

- (void)layerShakeHorizontal
{
    CAKeyframeAnimation *kfa = [CAKeyframeAnimation animationWithKeyPath:@"transform.translation.x"];
    CGFloat s = 5;
    kfa.values = @[@(-s),@(0),@(s),@(0),@(-s),@(0),@(s),@(0)];
    //时长
    kfa.duration = 0.3f;
    //重复
    kfa.repeatCount = 100;
    //移除
    kfa.removedOnCompletion = YES;
    [self addAnimation:kfa forKey:@"shake"];
}

- (void)layerShakeVertical
{
    CAKeyframeAnimation *kfaX = [CAKeyframeAnimation animationWithKeyPath:@"transform.translation.x"];
    CGFloat s = 5;
    kfaX.values = @[@(-s),@(0),@(s),@(0),@(-s),@(0),@(s),@(0)];
    //时长
    kfaX.duration = 0.3f;
    //重复
    kfaX.repeatCount = 0;
    //移除
    kfaX.removedOnCompletion = YES;
    
    CAKeyframeAnimation *kfaY = [CAKeyframeAnimation animationWithKeyPath:@"transform.translation.y"];
    //    CGFloat sY = 5;
    kfaY.values = @[@(-s),@(0),@(s),@(0),@(-s),@(0),@(s),@(0)];
    //时长
    kfaY.duration = 0.3f;
    //重复
    kfaY.repeatCount = 0;
    //移除
    kfaY.removedOnCompletion = YES;
    
    [self addAnimation:kfaY forKey:@"shake"];
}

- (void)layerShakeVerticalSlow
{
    CAKeyframeAnimation *kfa = [CAKeyframeAnimation animationWithKeyPath:@"transform.translation.y"];
    CGFloat s = 2;
    kfa.values = @[@(0),@(s),@(0),@(-s),@(0),@(s),@(0),@(s),@(0)];
    //时长
    kfa.duration = 4.f;
    //重复
    kfa.repeatCount = 100;
    //移除
    kfa.removedOnCompletion = YES;
    [self addAnimation:kfa forKey:@"shake"];
}

#pragma mark - Pop经典动画

- (void)layerPopScaleY
{
    POPBasicAnimation *animation = [POPBasicAnimation animationWithPropertyNamed:kPOPLayerTranslationY];
    //它会先缩小到(0.5,0.5),然后再去放大到(1.0,1.0)
    animation.fromValue = @1.0;
    animation.toValue = @0.8;
    animation.duration = 4.f;
    animation.repeatCount = HUGE_VALF;
    //动画结束之后的回调方法
    [animation setCompletionBlock:^(POPAnimation * animation, BOOL flag) {
    }];
    [self pop_addAnimation:animation forKey:@"SpringAnimation"];
    
    POPSpringAnimation* springAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerScaleXY];
    //它会先缩小到(0.5,0.5),然后再去放大到(1.0,1.0)
    springAnimation.fromValue = [NSValue valueWithCGPoint:CGPointMake(1.0, 0.8)];
    springAnimation.toValue =[NSValue valueWithCGPoint:CGPointMake(1.0, 1.0)];
    springAnimation.springBounciness = 20;
    springAnimation.springSpeed = 0.25f;
    springAnimation.repeatCount = HUGE_VALF;
    //动画结束之后的回调方法
    [springAnimation setCompletionBlock:nil];
    [self pop_addAnimation:springAnimation forKey:@"SpringAnimation"];
}

- (void)layerPopScaleY:(id)repeatCount
{
    POPBasicAnimation *animation = [POPBasicAnimation animationWithPropertyNamed:kPOPLayerTranslationY];
    //它会先缩小到(0.5,0.5),然后再去放大到(1.0,1.0)
    animation.fromValue = @1.0;
    animation.toValue = @0.8;
    animation.duration = 5.f;
    animation.repeatCount = [repeatCount integerValue];
    animation.removedOnCompletion = YES;
    //动画结束之后的回调方法
    [animation setCompletionBlock:^(POPAnimation * animation, BOOL flag) {
    }];
    [self pop_addAnimation:animation forKey:@"SpringAnimation"];
    
    POPSpringAnimation* springAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerScaleXY];
    //它会先缩小到(0.5,0.5),然后再去放大到(1.0,1.0)
    springAnimation.fromValue = [NSValue valueWithCGPoint:CGPointMake(1.0, 0.8)];
    springAnimation.toValue =[NSValue valueWithCGPoint:CGPointMake(1.0, 1.0)];
    springAnimation.springBounciness = 20;
    springAnimation.springSpeed = 0.25f;
    springAnimation.repeatCount = [repeatCount integerValue];
    //动画结束之后的回调方法
    [springAnimation setCompletionBlock:nil];
    [self pop_addAnimation:springAnimation forKey:@"SpringAnimation"];
}

/**
 Pop经典动画
 */
- (void)layerPopClassics
{
    POPSpringAnimation* springAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerScaleXY];
    //它会先缩小到(0.5,0.5),然后再去放大到(1.0,1.0)
    springAnimation.fromValue = [NSValue valueWithCGPoint:CGPointMake(0.5, 0.5)];
    springAnimation.toValue =[NSValue valueWithCGPoint:CGPointMake(1.0, 1.0)];
    springAnimation.springBounciness = 20;
    springAnimation.springSpeed = 2.f;
    springAnimation.repeatCount = HUGE_VALF;
    //动画结束之后的回调方法
    [springAnimation setCompletionBlock:^(POPAnimation * animation, BOOL flag) {
        
    }];
    [self pop_addAnimation:springAnimation forKey:@"SpringAnimation"];
}

- (void)layerPopClassicsWithTimes:(id)times
{
    POPSpringAnimation* springAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerScaleXY];
    //它会先缩小到(0.5,0.5),然后再去放大到(1.0,1.0)
    springAnimation.fromValue = [NSValue valueWithCGPoint:CGPointMake(0.5, 0.5)];
    springAnimation.toValue =[NSValue valueWithCGPoint:CGPointMake(1.0, 1.0)];
    springAnimation.springBounciness = 20;
    springAnimation.springSpeed = 2.f;
    if ([times intValue] == 0) {
        springAnimation.repeatCount = HUGE_VALF;
    }else{
        springAnimation.repeatCount = [times integerValue];
    }
    springAnimation.removedOnCompletion = YES;
    //动画结束之后的回调方法
    [springAnimation setCompletionBlock:^(POPAnimation * animation, BOOL flag) {
        
    }];
    [self pop_addAnimation:springAnimation forKey:@"SpringAnimation"];
}

- (void)layerPopClassicsWithTimes:(id)times completed:(kPopComplete)completed
{
    POPSpringAnimation* springAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerScaleXY];
    //它会先缩小到(0.5,0.5),然后再去放大到(1.0,1.0)
    springAnimation.fromValue = [NSValue valueWithCGPoint:CGPointMake(0.5, 0.5)];
    springAnimation.toValue =[NSValue valueWithCGPoint:CGPointMake(1.0, 1.0)];
    springAnimation.springBounciness = 15;
    springAnimation.springSpeed = 4.f;
    springAnimation.repeatCount = [times integerValue];
    //动画结束之后的回调方法
    springAnimation.completionBlock = completed;
    [self pop_addAnimation:springAnimation forKey:@"SpringAnimation"];
}

- (void)layerStopPopClassics
{
    POPSpringAnimation* springAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerScaleXY];
    //它会先缩小到(0.5,0.5),然后再去放大到(1.0,1.0)
    springAnimation.fromValue = [NSValue valueWithCGPoint:CGPointMake(1.0, 1.0)];
    springAnimation.toValue =[NSValue valueWithCGPoint:CGPointMake(1.0, 1.0)];
    springAnimation.springBounciness = 20;
    springAnimation.springSpeed = 2.f;
    springAnimation.repeatCount = 1;
    springAnimation.removedOnCompletion = YES;
    [self pop_addAnimation:springAnimation forKey:@"SpringAnimation"];
}

@end
